package com.phychips.rcp;


import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;

import android.util.Log;

import com.phychips.common.*;
import com.phychips.rcp.RcpResponse.targetType;

public class RcpApi2 extends BroadcastReceiver {
    private final boolean D = true;
    private RcpResponse m_RcpRespose = null;
    private iRcpEvent2 mRcpEvent2 = null;
    private iBluetoothEvent mBluetoothEvent = null;
    private ioType mIoType = null;
    private iRcp mIRcp = null;
    private int mDiscoveryCount = 0;
    private final String mPassword = "0925";
    private boolean isPasswordValidated = false;
    private boolean isOpen = false;
    private ReaderIo readerIo = null;
    //    private Context mContext = null;
    private static final RcpApi2 mInstance = new RcpApi2();

    private RcpApi2() {

    }

    public static RcpApi2 getInstance() {
        return mInstance;
    }

    public enum ioType {
        SERIAL, BLUETOOTH
    }

    public ReaderIo getIo() {
        return readerIo;
    }

    private void init(ioType io) {
        if (mIoType != io) {
            mIoType = io;
        } else {
            return;
        }

        if (mIoType == ioType.SERIAL) {
            m_RcpRespose = new RcpResponse(targetType.PR9200);
            m_RcpRespose.setRcpEvent(mRcpEvent2);

            mIRcp = new Rcp9200();

            readerIo = new SerialIo();
            readerIo.setOnBytesAvailableListener(m_RcpRespose
                    .getOnBytesAvailableListener());
        } else if (mIoType == ioType.BLUETOOTH) {
            m_RcpRespose = new RcpResponse(targetType.PR9200);
            m_RcpRespose.setRcpEvent(mRcpEvent2);

            mIRcp = new Rcp9200();

            readerIo = new BluetoothIo();
            readerIo.setOnBytesAvailableListener(m_RcpRespose
                    .getOnBytesAvailableListener());
        }
    }

    public void setOnRcpEventListener(iRcpEvent2 e) {
        mRcpEvent2 = e;

        if (m_RcpRespose != null) {
            m_RcpRespose.setRcpEvent(mRcpEvent2);
        }
    }

    public void setOnsetBluetoothEventListener(iBluetoothEvent e) {
        mBluetoothEvent = e;

        if (mIoType == ioType.BLUETOOTH)
            ((BluetoothIo) readerIo).setBluetoothEvent(mBluetoothEvent);
    }

    public boolean submitPassword(String password) {
        isPasswordValidated = password.equals(mPassword);

        return isPasswordValidated;
    }

    /**
     * This starts logging. The logged file is created in
     * /data/data/com.phychips/files/
     *
     * @param log : file name
     */
    public boolean startLog(String log) {
        boolean ret = true;

        try {
            ReaderIo.log_start(log);
        } catch (Exception exception2) {
            Log.e(getClass().getSimpleName(), exception2.toString());
            ret = false;
        }

        return ret;
    }

    /**
     * This stops logging.
     */
    public boolean stopLog() throws Exception {
        boolean ret = true;

        try {
            ReaderIo.log_stop();
        } catch (Exception exception2) {
            Log.e(getClass().getSimpleName(), exception2.toString());
            ret = false;
        }

        return ret;
    }

    public boolean open(ioType type) {
        boolean ret = true;

        try {
            init(type);
            readerIo.open();
            isOpen = true;
        } catch (Exception exception2) {
            Log.e(getClass().getSimpleName(), exception2.toString());
            ret = false;
        }

        return ret;
    }

    public boolean open() {
        boolean ret = true;

        try {
            init(ioType.SERIAL);
            readerIo.open();
            isOpen = true;
        } catch (Exception exception2) {
            Log.e(getClass().getSimpleName(), exception2.toString());
            ret = false;
        }

        return ret;
    }

    public boolean isOpen() {
        return this.isOpen;
    }

    /**
     * This close IO
     */
    public boolean close() {
        boolean ret = true;

        try {
            readerIo.close();
            isOpen = false;
        } catch (Exception exception2) {
            Log.e(getClass().getSimpleName(), exception2.toString());
            ret = false;
        }

        return ret;
    }

    /**
     * Start an automatic tag read operation, tag IDs are sent back to user
     * though notification packet.
     *
     * @param maxTags     maximum number of tag to read
     * @param maxTime     maximum elapsed time to tagging (sec)
     * @param repeatCycle Repeat cycle (how many times reader perform inventory
     *                    round).
     */
    public boolean startReadTags(
            int maxTags,
            int maxTime,
            int repeatCycle) {
        RcpPacket rcpPacket = RcpPacket.getInstance();

        if (!mIRcp.startReadTags(rcpPacket, maxTags, maxTime, repeatCycle))
            return false;

        boolean ret = true;

        try {
            readerIo.TransmitData(rcpPacket.packet, rcpPacket.packet_len);
        } catch (Exception exception2) {
            Log.e(getClass().getSimpleName(), exception2.toString());
            ret = false;
        }

        return ret;
    }

    /**
     * Start an automatic tag read operation, tag IDs are sent back to user
     * though notification packet.
     *
     * @param maxTags      maximum number of tag to read
     * @param maxTime      maximum elapsed time to tagging (sec)
     * @param repeat_cycle Repeat cycle (how many times reader perform inventory
     *                     round).
     */
    public boolean startReadTagsWithRssi(
            int maxTags,
            int maxTime,
            int repeatCycle) {
        RcpPacket rcpPacket = RcpPacket.getInstance();

        if (!mIRcp.startReadTagsWithRssi(rcpPacket, maxTags, maxTime, repeatCycle))
            return false;

        boolean ret = true;

        try {
            readerIo.TransmitData(rcpPacket.packet, rcpPacket.packet_len);
        } catch (Exception exception2) {
            Log.e(getClass().getSimpleName(), exception2.toString());
            ret = false;
        }

        return ret;
    }

    /**
     * Start an automatic tag read operation, tag IDs are sent back to user
     * though notification packet.
     *
     * @param maxTags     maximum number of tag to read
     * @param maxTime     maximum elapsed time to tagging (sec)
     * @param repeatCycle Repeat cycle (how many times reader perform inventory
     *                    round).
     */
    public boolean startReadTagsWithTid(
            int maxTags,
            int maxTime,
            int repeatCycle) {
        RcpPacket rcpPacket = RcpPacket.getInstance();

        //if(!mIRcp.startReadTagsWithTid(rcpPacket, maxTags, maxTime, repeatCycle))
        //return false;

        int cmd = 0xA0;
        int rssi = 0;
        int ant = 0;

        if (!mIRcp.startReadTagsEx2(rcpPacket, cmd, rssi, ant, maxTags, maxTime, repeatCycle))
            return false;

        boolean ret = true;

        try {
            readerIo.TransmitData(rcpPacket.packet, rcpPacket.packet_len);
        } catch (Exception exception2) {
            Log.e(getClass().getSimpleName(), exception2.toString());
            ret = false;
        }

        return ret;
    }

    /**
     * Stop an automatic read2 operation.
     */
    public boolean stopReadTags() {
        RcpPacket rcpPacket = RcpPacket.getInstance();

        if (!mIRcp.stopReadTags(rcpPacket))
            return false;

        boolean ret = true;

        try {
            readerIo.TransmitData(rcpPacket.packet, rcpPacket.packet_len);
        } catch (Exception exception2) {
            Log.e(getClass().getSimpleName(), exception2.toString());
            ret = false;
        }

        return ret;
    }

    /**
     * Get the current region. PR9200 uses individual channel table that depends
     * on region.
     */
    public boolean getRegion() {
        RcpPacket rcpPacket = RcpPacket.getInstance();

        if (!mIRcp.getRegion(rcpPacket))
            return false;

        boolean ret = true;

        try {
            readerIo.TransmitData(rcpPacket.packet, rcpPacket.packet_len);
        } catch (Exception exception2) {
            Log.e(getClass().getSimpleName(), exception2.toString());
            ret = false;
        }

        return ret;
    }

    /**
     * Get basic information from the reader.
     *
     * @param argument Model (0x00), S/N (0x01), Manufacturer (0x02), Frequency
     *                 (0x03), Tag Type (0x04)
     */
    public boolean getReaderInfo(int type) {
        RcpPacket rcpPacket = RcpPacket.getInstance();

        if (!mIRcp.getReaderInfo(rcpPacket, type))
            return false;

        boolean ret = true;

        try {
            readerIo.TransmitData(rcpPacket.packet, rcpPacket.packet_len);
        } catch (Exception exception2) {
            Log.e(getClass().getSimpleName(), exception2.toString());
            ret = false;
        }

        return ret;
    }


    /**
     * Set the current region. PR9200 uses individual channel table that depends
     * on region.
     *
     * @param region Korea (0x11), US (0x21), Europe (0x31), Japan (0x41), China1
     *               (0x51), China2 (0x52)
     * @throws RcpException
     */
    public boolean setRegion(int region) {
        // TODO 我注释的
//        if (!isPasswordValidated) {
//            Log.e(getClass().getSimpleName(), "ERROR - PASSWORD REQUIRED COMMAND");
//            return false;
//        }

        RcpPacket rcpPacket = RcpPacket.getInstance();

        if (!mIRcp.setRegion(rcpPacket, region))
            return false;

        boolean ret = true;

        try {
            readerIo.TransmitData(rcpPacket.packet, rcpPacket.packet_len);
        } catch (Exception exception2) {
            Log.e(getClass().getSimpleName(), exception2.toString());
            ret = false;
        }

        return ret;
    }

    /**
     * Get 18000-6C air interface protocol command ��Select�� parameters.
     */
    public boolean getSelectParam() {
        RcpPacket rcpPacket = RcpPacket.getInstance();

        if (!mIRcp.getTypeCSelectParam(rcpPacket))
            return false;

        boolean ret = true;

        try {
            readerIo.TransmitData(rcpPacket.packet, rcpPacket.packet_len);
        } catch (Exception exception2) {
            Log.e(getClass().getSimpleName(), exception2.toString());
            ret = false;
        }

        return ret;
    }

    /**
     * Set 18000-6C air interface protocol command ��Select�� parameters.
     *
     * @param param      target	S0 (000), S1 (001), S2 (010), S3 (011), SL (100)
     * @param action     Refer to ISO18000-6C
     * @param memoryBank RFU (00), EPC (01), TID (10), User (11)
     * @param pointer    Starting mask address
     * @param length     mask length bits
     * @param mask       Mask value
     */
    public boolean setSelectParam(
            int target,
            int action,
            int memoryBank,
            long pointer,
            int length,
            byte[] mask) {
        RcpTypeCSelect param = new RcpTypeCSelect(length);

        param.target = target;
        param.action = action;
        param.memoryBank = memoryBank;
        param.truncate = 0;
        param.pointer = pointer;
        param.length = length;
        param.mask = mask;

        RcpPacket rcpPacket = RcpPacket.getInstance();

        if (!mIRcp.setTypeCSelectParam(rcpPacket, param))
            return false;

        boolean ret = true;

        try {
            readerIo.TransmitData(rcpPacket.packet, rcpPacket.packet_len);
        } catch (Exception exception2) {
            Log.e(getClass().getSimpleName(), exception2.toString());
            ret = false;
        }

        return ret;
    }

    /**
     * Get 18000-6C air interface protocol command ��Query�� parameters.
     */
    public boolean getQueryParam() {
        RcpPacket rcpPacket = RcpPacket.getInstance();

        if (!mIRcp.getTypeCQueryParam(rcpPacket))
            return false;

        boolean ret = true;

        try {
            readerIo.TransmitData(rcpPacket.packet, rcpPacket.packet_len);
        } catch (Exception exception2) {
            Log.e(getClass().getSimpleName(), exception2.toString());
            ret = false;
        }

        return ret;
    }

    /**
     * Set 18000-6C air interface protocol command ��Query�� parameters.
     *
     * @param dr      DR=8 (0), DR=64/3 (1)
     * @param m       FM0 (00), M2 (01), M4 (10), M8 (11)
     * @param sel     All (00 or 01), ~SL (10), SL (11)
     * @param session S0 (00), S1 (01), S2 (10), S3 (11)
     * @param target  A (0), B (1)
     * @param q       0-15, the number of slots in the round
     */
    public boolean setQueryParam(
            int dr,
            int m,
            int trext,
            int sel,
            int session,
            int target,
            int q) {
        RcpPacket rcpPacket = RcpPacket.getInstance();
        RcpTypeCQuery param = new RcpTypeCQuery();

        param.queryDR = dr;
        param.queryM = m;
        param.trext = trext;
        param.sel = sel;
        param.session = session;
        param.target = target;
        param.slot_num = q;

        if (!mIRcp.setTypeCQueryParam(rcpPacket, param))
            return false;

        boolean ret = true;

        try {
            readerIo.TransmitData(rcpPacket.packet, rcpPacket.packet_len);
        } catch (Exception exception2) {
            Log.e(getClass().getSimpleName(), exception2.toString());
            ret = false;
        }

        return ret;
    }

    /**
     * Get RF channel. This command is valid only for non-FH mode.
     */
    public boolean getChannel() {
        RcpPacket rcpPacket = RcpPacket.getInstance();

        if (!mIRcp.getCurrChannel(rcpPacket))
            return false;

        boolean ret = true;

        try {
            readerIo.TransmitData(rcpPacket.packet, rcpPacket.packet_len);
        } catch (Exception exception2) {
            Log.e(getClass().getSimpleName(), exception2.toString());
            ret = false;
        }

        return ret;
    }

    /**
     * Set RF channel. This command is valid only for non-FHSS mode.
     *
     * @param channel       channel number
     * @param channelOffset channel offset
     */
    public boolean setChannel(int channel, int channelOffset) {
        if (!isPasswordValidated) {
            Log.e(getClass().getSimpleName(), "ERROR - PASSWORD REQUIRED COMMAND");
            return false;
        }

        RcpChannelInfo param = new RcpChannelInfo();
        param.channel_num = channel;
        param.channel_offset = channelOffset;

        RcpPacket rcpPacket = RcpPacket.getInstance();

        if (!mIRcp.setCurrChannel(rcpPacket, param))
            return false;

        boolean ret = true;

        try {
            readerIo.TransmitData(rcpPacket.packet, rcpPacket.packet_len);
        } catch (Exception exception2) {
            Log.e(getClass().getSimpleName(), exception2.toString());
            ret = false;
        }

        return ret;
    }

    public boolean getSession() {
        RcpPacket rcpPacket = RcpPacket.getInstance();

        if (!mIRcp.getSession(rcpPacket))
            return false;

        boolean ret = true;

        try {
            readerIo.TransmitData(rcpPacket.packet, rcpPacket.packet_len);
        } catch (Exception exception2) {
            Log.e(getClass().getSimpleName(), exception2.toString());
            ret = false;
        }

        return ret;
    }

    public boolean setSession(int session) {
        RcpPacket rcpPacket = RcpPacket.getInstance();

        if (!mIRcp.setSession(rcpPacket, session))
            return false;

        boolean ret = true;

        try {
            readerIo.TransmitData(rcpPacket.packet, rcpPacket.packet_len);
        } catch (Exception exception2) {
            Log.e(getClass().getSimpleName(), exception2.toString());
            ret = false;
        }

        return ret;
    }

    /**
     * Get FH and LBT control
     */
    public boolean getFhLbtParam() {
        RcpPacket rcpPacket = RcpPacket.getInstance();

        if (!mIRcp.getFhLbtParam(rcpPacket))
            return false;

        boolean ret = true;

        try {
            readerIo.TransmitData(rcpPacket.packet, rcpPacket.packet_len);
        } catch (Exception exception2) {
            Log.e(getClass().getSimpleName(), exception2.toString());
            ret = false;
        }

        return ret;
    }


    /**
     * Set FH and LBT Parameters
     *
     * @param readTime         Read Time (1 = 1ms)
     * @param idleTime         Idle Time (1 = 1ms)
     * @param carrierSenseTime Carrier Sense Time (1 = 1ms)
     * @param rfLevel          Target RF power level (-dBm x 10)
     * @param frequencyHopping enable (0x01) / disable (0x00)
     * @param listenBeforeTalk enable (0x01) / disable (0x00)
     * @param continuousWave   enable (0x01) / disable (0x00)
     */

    public boolean setFhLbtParam(
            int readTime,
            int idleTime,
            int carrierSenseTime,
            int rfLevel,
            int frequencyHopping,
            int listenBeforeTalk,
            int continuousWave) {
        RcpFhLbtParam param = new RcpFhLbtParam();

        param.readtime = readTime;
        param.idletime = idleTime;
        param.sensetime = carrierSenseTime;
        param.powerlevel = rfLevel;
        param.fhmode = frequencyHopping;
        param.lbtmode = listenBeforeTalk;
        param.cwmode = continuousWave;

        RcpPacket rcpPacket = RcpPacket.getInstance();

        if (!mIRcp.setFhLbtParam(rcpPacket, param))
            return false;

        boolean ret = true;

        try {
            readerIo.TransmitData(rcpPacket.packet, rcpPacket.packet_len);
        } catch (Exception exception2) {
            Log.e(getClass().getSimpleName(), exception2.toString());
            ret = false;
        }

        return ret;
    }

    /**
     * Get Output power level.
     */
    public boolean getOutputPowerLevel() {
        RcpPacket rcpPacket = RcpPacket.getInstance();

        if (!mIRcp.getOutputPowerLevel(rcpPacket))
            return false;

        boolean ret = true;

        try {
            readerIo.TransmitData(rcpPacket.packet, rcpPacket.packet_len);
        } catch (Exception exception2) {
            Log.e(getClass().getSimpleName(), exception2.toString());
            ret = false;
        }

        return ret;
    }

    /**
     * Set current Tx power level.
     *
     * @param power_level PR9200 Power
     */
    public boolean setOutputPowerLevel(int power_level) {
        RcpPacket rcpPacket = RcpPacket.getInstance();

        if (!mIRcp.setOutputPowerLevel(rcpPacket, (byte) (power_level & 0xff)))
            return false;

        boolean ret = true;

        try {
            readerIo.TransmitData(rcpPacket.packet, rcpPacket.packet_len);
        } catch (Exception exception2) {
            Log.e(getClass().getSimpleName(), exception2.toString());
            ret = false;
        }

        return ret;
    }

    /**
     * Turn the Continuous Wave (CW) signal on/off. This command packet is only
     * valid for idle mode.
     *
     * @param control On (0xFF), Off (0x00)
     */
    public boolean setRfCw(int control) {
        if (!isPasswordValidated) {
            Log.e(getClass().getSimpleName(), "ERROR - PASSWORD REQUIRED COMMAND");
            return false;
        }

        RcpPacket rcpPacket = RcpPacket.getInstance();

        if (!mIRcp.setRfCw(rcpPacket, control))
            return false;

        boolean ret = true;

        try {
            readerIo.TransmitData(rcpPacket.packet, rcpPacket.packet_len);
        } catch (Exception exception2) {
            Log.e(getClass().getSimpleName(), exception2.toString());
            ret = false;
        }

        return ret;
    }

    /**
     * Read Type C user data from specified memory bank.
     *
     * @param param RcpTypeCTag (EPC length, EPC, starting address, data length)
     */
    public boolean readUserMemory(
            byte[] epc,
            int startAddress,
            int dataLength) {
        RcpTypeCTag param = new RcpTypeCTag(epc.length, dataLength);

        RcpPacket rcpPacket = RcpPacket.getInstance();

        if (!mIRcp.ReadTypeCUserData(rcpPacket, param))
            return false;

        boolean ret = true;

        try {
            readerIo.TransmitData(rcpPacket.packet, rcpPacket.packet_len);
        } catch (Exception exception2) {
            Log.e(getClass().getSimpleName(), exception2.toString());
            ret = false;
        }

        return ret;
    }

    /**
     * Read Type C tag data from specified memory bank.
     *
     * @param accessPassword Password if target memory bank was password protected.
     * @param epc            Target tag��s EPC
     * @param memoryBank     Target memory bank; RFU (0x00), EPC (0x01), TID (0x02), User (0x03)
     * @param startAddress   Starting Address word pointer
     * @param dataLength     Data Length (Word Count) or Generic command length (Bit Count)
     */
    public boolean readFromTagMemory(
            long accessPassword,
            byte[] epc,
            int memoryBank,
            int startAddress,
            int dataLength) {
        RcpTypeCTag param = new RcpTypeCTag(epc.length, dataLength);
        param.password = accessPassword;
        param.epc = epc;
        param.memory_bank = memoryBank;
        param.start_address = startAddress;
        param.data_length = dataLength;

        RcpPacket rcpPacket = RcpPacket.getInstance();

        if (!mIRcp.readFromTagMemory(rcpPacket, param))
            return false;

        boolean ret = true;

        try {
            readerIo.TransmitData(rcpPacket.packet, rcpPacket.packet_len);
        } catch (Exception exception2) {
            Log.e(getClass().getSimpleName(), exception2.toString());
            ret = false;
        }

        return ret;
    }

    /**
     * Read Type C tag data from specified memory bank.
     *
     * @param accessPassword Password if target memory bank was password protected.
     * @param epc            Target tag��s EPC
     * @param memoryBank     Target memory bank; RFU (0x00), EPC (0x01), TID (0x02), User (0x03)
     * @param startAddress   Starting Address word pointer
     * @param dataLength     Data Length (Word Count) or Generic command length (Bit Count)
     */
    public boolean readFromTagMemoryLong(
            long accessPassword,
            byte[] epc,
            int memoryBank,
            int startAddress,
            int dataLength) {
        RcpTypeCTag param = new RcpTypeCTag(epc.length, dataLength);
        param.password = accessPassword;
        param.epc = epc;
        param.memory_bank = memoryBank;
        param.start_address = startAddress;
        param.data_length = dataLength;

        RcpPacket rcpPacket = RcpPacket.getInstance();

        if (!mIRcp.readLongTag(rcpPacket, param))
            return false;

        boolean ret = true;

        try {
            readerIo.TransmitData(rcpPacket.packet, rcpPacket.packet_len);
        } catch (Exception exception2) {
            Log.e(getClass().getSimpleName(), exception2.toString());
            ret = false;
        }

        return ret;
    }

    /**
     * Get current frequency hopping table.
     */
    public boolean getFreqHoppingTable() {
        RcpPacket rcpPacket = RcpPacket.getInstance();

        if (!mIRcp.getFreqHoppingTable(rcpPacket))
            return false;

        boolean ret = true;

        try {
            readerIo.TransmitData(rcpPacket.packet, rcpPacket.packet_len);
        } catch (Exception exception2) {
            Log.e(getClass().getSimpleName(), exception2.toString());
            ret = false;
        }

        return ret;
    }


    /**
     * Write type C tag data.
     *
     * @param accessPassword Password if target memory bank was password protected. 	Otherwise, set AP filed to 0x00000000.
     * @param epc            Target tag��s EPC
     * @param memoryBank     Target memory bank; RFU (0x00), EPC (0x01), TID (0x02), User (0x03)
     * @param startAddress   Starting Address word pointer
     * @param data           Data to write
     */
    public boolean writeToTagMemory(
            long accessPassword,
            byte[] epc,
            int memoryBank,
            int startAddress,
            byte[] data) {
        RcpTypeCTag param = new RcpTypeCTag(epc.length, data.length / 2);
        param.password = accessPassword;
        param.epc = epc;
        param.memory_bank = memoryBank;
        param.start_address = startAddress;
        param.data = data;

        RcpPacket rcpPacket = RcpPacket.getInstance();

        if (!mIRcp.writeToTagMemory(rcpPacket, param))
            return false;

        boolean ret = true;

        try {
            readerIo.TransmitData(rcpPacket.packet, rcpPacket.packet_len);
        } catch (Exception exception2) {
            Log.e(getClass().getSimpleName(), exception2.toString());
            ret = false;
        }

        return ret;
    }

    /**
     * Block write type C tag data.
     *
     * @param accessPassword Password if target memory bank was password protected. 	Otherwise, set AP filed to 0x00000000.
     * @param epc            Target tag��s EPC
     * @param memoryBank     Target memory bank; RFU (0x00), EPC (0x01), TID (0x02), User (0x03)
     * @param startAddress   Starting Address word pointer
     * @param data           Data to write
     */
    public boolean blockwriteToTagMemory(
            long accessPassword,
            byte[] epc,
            int memoryBank,
            int startAddress,
            byte[] data) {
        RcpTypeCTag param = new RcpTypeCTag(epc.length, data.length / 2);
        param.password = accessPassword;
        param.epc = epc;
        param.memory_bank = memoryBank;
        param.start_address = startAddress;
        param.data = data;

        RcpPacket rcpPacket = RcpPacket.getInstance();

        if (!mIRcp.blockwriteToTagMemory(rcpPacket, param))
            return false;

        boolean ret = true;

        try {
            readerIo.TransmitData(rcpPacket.packet, rcpPacket.packet_len);
        } catch (Exception exception2) {
            Log.e(getClass().getSimpleName(), exception2.toString());
            ret = false;
        }

        return ret;
    }

    /**
     * Block erases type C tag data.
     *
     * @param accessPassword Password if target memory bank was password protected.
     * @param epc            Target tag��s EPC
     * @param memoryBank     Target memory bank; RFU (0x00), EPC (0x01), TID (0x02), User (0x03)
     * @param startAddress   Starting Address word pointer
     * @param dataLength     Data Length (Word Count)
     */
    public boolean blockeraseTagMemory(
            long accessPassword,
            byte[] epc,
            int memoryBank,
            int startAddress,
            int dataLength) {
        RcpTypeCTag param = new RcpTypeCTag(epc.length, dataLength);
        param.password = accessPassword;
        param.epc = epc;
        param.memory_bank = memoryBank;
        param.start_address = startAddress;
        param.data_length = dataLength;

        RcpPacket rcpPacket = RcpPacket.getInstance();

        if (!mIRcp.blockeraseTagMemory(rcpPacket, param))
            return false;

        boolean ret = true;

        try {
            readerIo.TransmitData(rcpPacket.packet, rcpPacket.packet_len);
        } catch (Exception exception2) {
            Log.e(getClass().getSimpleName(), exception2.toString());
            ret = false;
        }

        return ret;
    }

    /**
     * Kill a Tag.
     *
     * @param param        : RcpTypeCTag (password, EPC length, EPC, recom)
     * @param killPassword Kill Password
     * @param epc          Target tag��s EPC
     * @param recom        Recommissioning bits
     */
    public boolean killTag(
            long killPassword,
            byte[] epc) {
        RcpTypeCTag param = new RcpTypeCTag(epc.length, 0);
        param.password = killPassword;
        param.epc = epc;
        param.recom = 0;

        RcpPacket rcpPacket = RcpPacket.getInstance();

        if (!mIRcp.killTag(rcpPacket, param))
            return false;

        boolean ret = true;

        try {
            readerIo.TransmitData(rcpPacket.packet, rcpPacket.packet_len);
        } catch (Exception exception2) {
            Log.e(getClass().getSimpleName(), exception2.toString());
            ret = false;
        }

        return ret;
    }

    /**
     * Lock an indicated memory bank in the tag.
     *
     * @param param          : RcpTypeCTag (password, EPC length, EPC, Lock mask and action
     *                       flags)
     * @param accessPassword Password if target memory bank was password protected.
     * @param epc            Target tag��s EPC
     * @param lockData       Lock mask and action flags. Each is 10 bits and 4-bit zeros (dummy) are padded to the left.
     */

    public boolean lockTagMemory(
            long accessPassword,
            byte[] epc,
            int lockData) {
        RcpTypeCTag param = new RcpTypeCTag(epc.length, 0);
        param.password = accessPassword;
        param.epc = epc;
        param.lock_mask = lockData;

        RcpPacket rcpPacket = RcpPacket.getInstance();

        if (!mIRcp.lockTagMemory(rcpPacket, param))
            return false;

        boolean ret = true;

        try {
            readerIo.TransmitData(rcpPacket.packet, rcpPacket.packet_len);
        } catch (Exception exception2) {
            Log.e(getClass().getSimpleName(), exception2.toString());
            ret = false;
        }

        return ret;
    }

    /**
     * Get current temperature.
     */
    public boolean getTemperature() {
        RcpPacket rcpPacket = RcpPacket.getInstance();

        if (!mIRcp.getTemperature(rcpPacket))
            return false;

        boolean ret = true;

        try {
            readerIo.TransmitData(rcpPacket.packet, rcpPacket.packet_len);
        } catch (Exception exception2) {
            Log.e(getClass().getSimpleName(), exception2.toString());
            ret = false;
        }

        return ret;
    }

    /**
     * Get RSSI level
     */
    public boolean getRssi() {
        RcpPacket rcpPacket = RcpPacket.getInstance();

        if (!mIRcp.getRssi(rcpPacket))
            return false;

        boolean ret = true;

        try {
            readerIo.TransmitData(rcpPacket.packet, rcpPacket.packet_len);
        } catch (Exception exception2) {
            Log.e(getClass().getSimpleName(), exception2.toString());
            ret = false;
        }

        return ret;
    }

    /**
     * Sets Registry Update function
     *
     * @param action
     */
    public boolean updateRegistry(int action) {
        if (!isPasswordValidated) {
            Log.e(getClass().getSimpleName(), "ERROR - PASSWORD REQUIRED COMMAND");
            return false;
        }

        RcpPacket rcpPacket = RcpPacket.getInstance();

        if (mIRcp.updateRegistry(rcpPacket, action))
            return false;

        boolean ret = true;

        try {
            readerIo.TransmitData(rcpPacket.packet, rcpPacket.packet_len);
        } catch (Exception exception2) {
            Log.e(getClass().getSimpleName(), exception2.toString());
            ret = false;
        }

        return ret;
    }

    /**
     * Sets Registry Erase function.
     *
     * @param action
     */
    public boolean eraseRegistry(int action) {
        if (!isPasswordValidated) {
            Log.e(getClass().getSimpleName(), "ERROR - PASSWORD REQUIRED COMMAND");
            return false;
        }

        RcpPacket rcpPacket = RcpPacket.getInstance();

        if (!mIRcp.eraseRegistry(rcpPacket, action))
            return false;

        boolean ret = true;

        try {
            readerIo.TransmitData(rcpPacket.packet, rcpPacket.packet_len);
        } catch (Exception exception2) {
            Log.e(getClass().getSimpleName(), exception2.toString());
            ret = false;
        }

        return ret;
    }

    /**
     * Gets Registry items.
     *
     * @param item : Registry Version (0x0000), Firmware Date (0x0001), Band
     *             (0x0002), Tx power (0x0003), FH/LBT (0x0004), Anti-collision
     *             Mode (0x0005), Modulation Mode (0x0006), Query(Q) (0x0007),
     *             Frequency Hopping Table (0x0008), Tx Power Table (0x0009)
     */
    public boolean getRegistry(int item) {
        RcpPacket rcpPacket = RcpPacket.getInstance();

        if (!mIRcp.getRegistry(rcpPacket, item))
            return false;

        boolean ret = true;

        try {
            readerIo.TransmitData(rcpPacket.packet, rcpPacket.packet_len);
        } catch (Exception exception2) {
            Log.e(getClass().getSimpleName(), exception2.toString());
            ret = false;
        }

        return ret;
    }

    public boolean getBeep() {
        RcpPacket rcpPacket = RcpPacket.getInstance();

        if (!mIRcp.getBeep(rcpPacket))
            return false;

        boolean ret = true;

        try {
            readerIo.TransmitData(rcpPacket.packet, rcpPacket.packet_len);
        } catch (Exception exception2) {
            Log.e(getClass().getSimpleName(), exception2.toString());
            ret = false;
        }

        return ret;
    }

    public boolean setBeep(boolean state) {
        RcpPacket rcpPacket = RcpPacket.getInstance();

        if (!mIRcp.setBeep(rcpPacket, state))
            return false;

        boolean ret = true;

        try {
            readerIo.TransmitData(rcpPacket.packet, rcpPacket.packet_len);
        } catch (Exception exception2) {
            Log.e(getClass().getSimpleName(), exception2.toString());
            ret = false;
        }

        return ret;
    }

    public boolean calGpAdc(int min, int max) {
        RcpPacket rcpPacket = RcpPacket.getInstance();

        if (!mIRcp.calGpAdc(rcpPacket, min, max))
            return false;

        boolean ret = true;

        try {
            readerIo.TransmitData(rcpPacket.packet, rcpPacket.packet_len);
        } catch (Exception exception2) {
            Log.e(getClass().getSimpleName(), exception2.toString());
            ret = false;
        }

        return ret;
    }

    public boolean testReader(int type) {
        RcpPacket rcpPacket = RcpPacket.getInstance();

        if (!mIRcp.testReader(rcpPacket, type))
            return false;

        boolean ret = true;

        try {
            readerIo.TransmitData(rcpPacket.packet, rcpPacket.packet_len);
        } catch (Exception exception2) {
            Log.e(getClass().getSimpleName(), exception2.toString());
            ret = false;
        }

        return ret;
    }

    /**
     * Send a generic ePC command for EM4325.
     *
     * @param param TS, password, RM, EPC length, EPC, SZ, GC length, GC
     */
    public boolean genericTransport(
            long accessPassword,
            byte[] epc,
            int ts,
            int rm,
            int gcBitLen,
            byte[] gc) {
        RcpTypeCTag param = new RcpTypeCTag(epc.length, gcBitLen);
        param.password = accessPassword;
        param.epc = epc;
        param.ts = (byte) (ts & 0xff);
        param.rm = (byte) (rm & 0xff);
        param.data = gc;

        RcpPacket rcpPacket = RcpPacket.getInstance();

        if (!mIRcp.genericTransport(rcpPacket, param))
            return false;

        boolean ret = true;

        try {
            readerIo.TransmitData(rcpPacket.packet, rcpPacket.packet_len);
        } catch (Exception exception2) {
            Log.e(getClass().getSimpleName(), exception2.toString());
            ret = false;
        }

        return ret;
    }

    /**
     * This directly send the command packet to RFID reader. It returns the
     * response packet in byte array. Auto read / stop are not supported.
     *
     * @param packet : command packet
     */
    public boolean nativeRcp(byte[] packet) {
        RcpPacket rcpPacket = RcpPacket.getInstance();

        if (!mIRcp.nativeRcp(rcpPacket, packet))
            return false;

        boolean ret = true;

        try {
            readerIo.TransmitData(rcpPacket.packet, rcpPacket.packet_len);
        } catch (Exception exception2) {
            Log.e(getClass().getSimpleName(), exception2.toString());
            ret = false;
        }

        return ret;
    }

    /**
     * Authentication.
     */
    public boolean authentication(boolean itemLevel, byte[] ich, byte[] tag) {
        RcpPacket rcpPacket = RcpPacket.getInstance();

        if (!mIRcp.authentication(rcpPacket, itemLevel, ich, tag))
            return false;

        boolean ret = true;

        try {
            readerIo.TransmitData(rcpPacket.packet, rcpPacket.packet_len);
        } catch (Exception exception2) {
            Log.e(getClass().getSimpleName(), exception2.toString());
            ret = false;
        }

        return ret;
    }

    /**
     * Authentication.
     */
    public boolean authenticationEx(boolean itemLevel, byte[] ich, byte[] tag) {
        RcpPacket rcpPacket = RcpPacket.getInstance();

        if (!mIRcp.authenticationEx(rcpPacket, itemLevel, ich, tag))
            return false;

        boolean ret = true;

        try {
            readerIo.TransmitData(rcpPacket.packet, rcpPacket.packet_len);
        } catch (Exception exception2) {
            Log.e(getClass().getSimpleName(), exception2.toString());
            ret = false;
        }

        return ret;
    }

    /**
     * Untraceable.
     */
    public boolean untraceable(byte[] password, byte[] tag, byte uflag, byte epc, byte tid, byte user, byte range) {
        RcpPacket rcpPacket = RcpPacket.getInstance();

        if (!mIRcp.untraceable(rcpPacket, password, tag, uflag, epc, tid, user, range))
            return false;

        boolean ret = true;

        try {
            readerIo.TransmitData(rcpPacket.packet, rcpPacket.packet_len);
        } catch (Exception exception2) {
            Log.e(getClass().getSimpleName(), exception2.toString());
            ret = false;
        }

        return ret;
    }

    /**
     * Untraceable.
     */
    public boolean untraceableEx(byte[] password, byte[] tag, byte uflag, byte epc, byte tid, byte user, byte range) {
        RcpPacket rcpPacket = RcpPacket.getInstance();

        if (!mIRcp.untraceableEx(rcpPacket, password, tag, uflag, epc, tid, user, range))
            return false;

        boolean ret = true;

        try {
            readerIo.TransmitData(rcpPacket.packet, rcpPacket.packet_len);
        } catch (Exception exception2) {
            Log.e(getClass().getSimpleName(), exception2.toString());
            ret = false;
        }

        return ret;
    }

    /**
     * Read Signature.
     */

    public boolean readSignature(byte[] password, byte[] tag, byte ptr, byte cnt) {
        RcpPacket rcpPacket = RcpPacket.getInstance();

        if (!mIRcp.readSignature(rcpPacket, password, tag, ptr, cnt))
            return false;

        boolean ret = true;

        try {
            readerIo.TransmitData(rcpPacket.packet, rcpPacket.packet_len);
        } catch (Exception exception2) {
            Log.e(getClass().getSimpleName(), exception2.toString());
            ret = false;
        }

        return ret;
    }

    public boolean FERtest() {
        RcpPacket rcpPacket = RcpPacket.getInstance();

        if (!mIRcp.FERtest(rcpPacket))
            return false;

        boolean ret = true;

        try {
            readerIo.TransmitData(rcpPacket.packet, rcpPacket.packet_len);
        } catch (Exception exception2) {
            Log.e(getClass().getSimpleName(), exception2.toString());
            ret = false;
        }

        return ret;
    }

    public boolean loopBackTest() {
        RcpPacket rcpPacket = RcpPacket.getInstance();

        if (!mIRcp.loopBackTest(rcpPacket))
            return false;

        boolean ret = true;

        try {
            readerIo.TransmitData(rcpPacket.packet, rcpPacket.packet_len);
        } catch (Exception exception2) {
            Log.e(getClass().getSimpleName(), exception2.toString());
            ret = false;
        }

        return ret;
    }

    public boolean waveTest(int data) {
        RcpPacket rcpPacket = RcpPacket.getInstance();

        if (!mIRcp.waveTest(rcpPacket, data))
            return false;

        boolean ret = true;

        try {
            readerIo.TransmitData(rcpPacket.packet, rcpPacket.packet_len);
        } catch (Exception exception2) {
            Log.e(getClass().getSimpleName(), exception2.toString());
            ret = false;
        }

        return ret;
    }

    @Override
    public void onReceive(Context arg0, Intent intent) {
        System.out.println("onReceive");

        if (D)
            System.out.println(intent.toString());

        String i = intent.getAction();

        if (mIoType == ioType.BLUETOOTH) {
            BluetoothIo io = (BluetoothIo) readerIo;

            if (io.getBluetoothApi() == null)
                return;

            if (i.equalsIgnoreCase(BluetoothAdapter.ACTION_DISCOVERY_STARTED)) {
                if (mBluetoothEvent != null)
                    mBluetoothEvent.onDiscovering();
                // m_btDiscoveryState = true;
            } else if (i.equalsIgnoreCase(BluetoothAdapter.ACTION_DISCOVERY_FINISHED)) {
                // m_btDiscoveryState = false;
                String address = io.getBluetoothApi().getTargetAddress();
                if (address != null) {
                    if (mBluetoothEvent != null)
                        mBluetoothEvent.onDiscoveredAndConnecting();

                    io.getBluetoothApi().connect(address);
                } else {
                    if (mDiscoveryCount < 3) {
                        io.getBluetoothApi().startDiscovery();
                        mDiscoveryCount++;
                    } else {
                        mDiscoveryCount = 0;

                        if (mBluetoothEvent != null)
                            mBluetoothEvent.onDiscoveredAndNotFound();
                    }
                }

            }

            // 3. Bluetooth Device
            else if (i.equalsIgnoreCase(BluetoothDevice.ACTION_ACL_CONNECTED)) {
//		if(mBluetoothEvent != null)
//		    mBluetoothEvent.onConnected();
            } else if (i
                    .equalsIgnoreCase(BluetoothDevice.ACTION_ACL_DISCONNECTED)) {
                if (mBluetoothEvent != null)
                    mBluetoothEvent.onDisconnected();
            } else if (i
                    .equalsIgnoreCase(BluetoothDevice.ACTION_BOND_STATE_CHANGED)) {
                int bondState = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, -1);

                System.out.println("EXTRA_BOND_STATE : " + bondState);

                switch (bondState) {
                    case BluetoothDevice.BOND_NONE:
                        if (mBluetoothEvent != null)
                            mBluetoothEvent.onNotFaired();
                        break;
                    case BluetoothDevice.BOND_BONDING:
                        if (mBluetoothEvent != null)
                            mBluetoothEvent.onFairing();
                        break;
                    case BluetoothDevice.BOND_BONDED:
//		    if(mBluetoothEvent != null)
//			mBluetoothEvent.onConnected();
                        break;
                }
            } else if (i.equalsIgnoreCase(BluetoothDevice.ACTION_FOUND)) {
                String address = io.getBluetoothApi().getDiscoveredAddress(intent);
                if (address != null) {
                    io.getBluetoothApi().stopDiscovery();
                    io.getBluetoothApi().setTargetAddress(address);
                }
            } else if (i
                    .equalsIgnoreCase(BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED)) {
            } else if (i
                    .equalsIgnoreCase(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE)) {
            } else if (i.equalsIgnoreCase(BluetoothAdapter.ACTION_REQUEST_ENABLE)) {
            } else if (i
                    .equalsIgnoreCase(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED)) {
            } else if (i.equalsIgnoreCase(BluetoothAdapter.ACTION_STATE_CHANGED)) {

            } else if (i
                    .equalsIgnoreCase(BluetoothDevice.ACTION_ACL_DISCONNECT_REQUESTED)) {

            } else if (i.equalsIgnoreCase(BluetoothDevice.ACTION_CLASS_CHANGED)) {

            } else if (i.equalsIgnoreCase(BluetoothDevice.ACTION_NAME_CHANGED)) {

            }
        }
    }
}
